#include <iostream>
#include <conio.h>
#include <string>
#include "task_group.h"

#define DEBUG true
#define KEY_Q 113
#define KEY_J 106
#define KEY_K 107
#define KEY_L 108
#define KEY_H 104
#define KEY_TAB 9
#define KEY_ENTER 13
#define KEY_SPACE 32
#define KEY_BACKSPACE 8
#define KEY_SHIFT_ENTER 99

void printDebug(Task *current, int key)
{
  std::cout << "======== Debug =======" << std::endl;

  std::cout << "Pass key code: " << key << std::endl;
  std::cout << "text: ";
  if (current != nullptr)
    std::cout << current->get_text();
  std::cout << std::endl;

  std::cout << "parent text: ";
  if (current != nullptr)
    std::cout << current->get_parent()->get_text();
  std::cout << std::endl;

  std::cout << "======== Debug =======" << std::endl;
}

void run(TaskGroup *group)
{
  int key;
  int is_running = true;
  std::string text;
  Task *delete_task;
  while (is_running)
  {
    system("cls");
    if (DEBUG)
    {
      printDebug(group->get_current(), key);
    }

    group->print_group(group->get_root()->get_child_head(), 0);
    key = _getch();
    switch (key)
    {
    case KEY_Q:
      is_running = false;
      break;

    case KEY_H:
      group->move_to_parent();
      break;

    case KEY_J:
      group->move_to_next();
      break;

    case KEY_K:
      group->move_to_prev();
      break;

    case KEY_L:
      if (group->get_current() != nullptr && group->get_current()->get_child_head() != nullptr)
      {
        group->set_current(group->get_current()->get_child_head());
      }
      break;

    case KEY_BACKSPACE:
      group->delete_current_and_move();
      break;

    case KEY_ENTER:
      std::cout << "Enter data: ";
      std::getline(std::cin, text);
      group->append(text);
      break;

    case KEY_SHIFT_ENTER:
      std::cout << "Enter data: ";
      std::getline(std::cin, text);
      group->insert(text);
      break;

    case KEY_TAB:
      std::cout << "Enter data: ";
      std::getline(std::cin, text);
      group->add_to_child_first(text);
      break;

    case KEY_SPACE:
      group->get_current()->change_status();
      break;

    default:
      break;
    }
  }
}

int main()
{
  TaskGroup *group = new TaskGroup("Group 1");

  run(group);

  group->free_tasks_memory(group->get_root());

  delete group;
  return 0;
}